/*
 * src/lexical/common.c
 * 
 * Harry Wei <harryxiyou@gmail.com> (C) 2012
 *
 * Funcs in common use, these codes are under GPL.
 */
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "cp_ctrl.h"

int add_element(struct la *ctrl, char *ch) {
	g_message("enter func %s", __func__);
	struct stack *tmp = g_malloc0(sizeof(struct stack));
	if (NULL == tmp) {
		g_message("%s -- Allocate error!", __func__);
		return -1;
	}
	sprintf(tmp->ch, "%s", ch);
	tmp->next = ctrl->ss->next;
	g_message("content is %s", ch);
	ctrl->ss->next = tmp;
	ctrl->ss_len += 1;
	g_message("leave func %s", __func__);
	return 0;
}

int rm_element(struct la *ctrl) {
	g_message("enter func %s", __func__);
	struct stack *tmp = ctrl->ss->next;
	ctrl->ss->next = tmp->next;
	free(tmp);
	ctrl->ss_len -= 1;
	g_message("leave func %s", __func__);
	return 0;
}

int textbuf2ctrl(struct la *ctrl, char *filename, char *buf) {
	g_message("enter func %s", __func__);
	if (NULL == ctrl || NULL == filename || NULL == buf) {
		g_message("%s -- Parameter error!", __func__);
		return -1;
	}
	g_message("%s -- ctrl[%p], filename[%s], buf[%p]", __func__, ctrl, filename, buf);
	if (TRUE == g_str_has_suffix(filename, "c")) {
		g_message("%s -- 999 ctrl[%p], filename[%s], buf[%p]", __func__, ctrl, filename, buf);
		return 1; // This is a c source file
	}
	g_message("%s -- ctrl[%p], filename[%s], buf[%p]", __func__, ctrl, filename, buf);
	int i = 0;
	char *endptr = NULL;
	gchar **v = g_strsplit(buf, "@@##$$", 1024);
	//gchar *_filename = g_strdup(filename);
	if (TRUE == g_str_has_prefix(filename, KEYFILE)) {
		g_message("%s -- keyfile branch, v[0] is %s", __func__, v[0]);
		g_message("%s -- keyword_buf[%p]", __func__, ctrl->keyword_buff);
		struct table *_buf = (struct table *) ctrl->keyword_buff;
		g_message("%s -- keyword_buf[%p]", __func__, _buf);
		ctrl->kd_amount = g_strv_length(v) - 1;
		for (i = 1; i < g_strv_length(v) - 1; i++) {
			_buf->code = strtoul(v[0], &endptr, 0) ;
			sprintf(_buf->ch, "%s", v[i]);
			_buf += 1;
		}
	} else if (TRUE == g_str_has_prefix(filename, DELIMITERFILE)) {
		ctrl->dt_amount = g_strv_length(v) - 1;
		struct table *_buf = (struct table *) ctrl->delimiter_buff;
		for (i = 1; i < g_strv_length(v) - 1; i++) {
			_buf->code = strtoul(v[0], &endptr, 0) ;
			sprintf(_buf->ch, "%s", v[i]);
			_buf += 1;
		}
	} else if (TRUE == g_str_has_prefix(filename, OPERATORFILE)) {
		ctrl->op_amount = g_strv_length(v) - 1;
		struct table *_buf = (struct table *) ctrl->operator_buff;
		for (i = 1; i < g_strv_length(v) - 1; i++) {
			_buf->code = strtoul(v[0], &endptr, 0) ;
			sprintf(_buf->ch, "%s", v[i]);
			_buf += 1;
		}
	} else {
		g_message("%s -- error, No this kind of type!", __func__);
		return -1;
	}
	g_strfreev(v);
	g_message("leave func %s", __func__);
	return 0;
}

int read_contents(struct la *ctrl, char *filename) {
	g_message("enter func %s", __func__);
	if (NULL == ctrl || NULL == filename) {
		g_message("%s -- Parameter error!", __func__);
		return -1;
	}
	char buf[BUF_LEN];
	memset(buf, '\0', BUF_LEN);
	int ret = 0;
	int fd = open(filename, O_RDONLY);
	if (fd == -1) {
		g_message("%s -- Read file %s error!", __func__, filename);
		return -1;
	}
	struct stat fst; //file stat
	memset(&fst, 0, sizeof(struct stat));
	fstat(fd, &fst);
	/*XXX buf can not beyond length of BUF_LEN*/
	if (fst.st_size > (off_t) BUF_LEN) {
		g_message("Error, file length can not beyond %d Bytes", (int) BUF_LEN);
		return -1;
	}
	if (fst.st_size != read(fd, buf, fst.st_size)) { 
		g_message("%s -- read file %s error!", __func__, filename);
		return -1;
	}
	g_message("%s -- file %s's contents are [%s]", __func__, filename, buf);
	close(fd);
	ret = textbuf2ctrl(ctrl, filename, buf);
	if (1 == ret) {
		g_message("%s -- ctrl->buff[%p]", __func__, ctrl->buff);
		//sprintf(ctrl->buff, "%s", buf);
		g_message("%s -- file size is [%lu]", __func__, fst.st_size);
		g_strlcpy(ctrl->buff, buf, fst.st_size);
	}
	g_assert(ret != -1);
	g_message("leave func %s", __func__);
	return 0;
}

int handle_error(void) {
	g_print("Compiler Analyser Error!\n");
	return 0;
}
